package com.suning.sawp.service.impl.yxwt;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import redis.clients.jedis.Jedis;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimaps;
import com.suning.framework.sedis.JedisAction;
import com.suning.framework.sedis.JedisClient;
import com.suning.lsq.rsf.bean.request.QueryLogisticsDetailsForposRequest;
import com.suning.lsq.rsf.bean.response.QueryLogisticsDetailsForpos;
import com.suning.lsq.rsf.bean.response.QueryLogisticsDetailsForposResponse;
import com.suning.lsq.rsf.bean.response.QueryLogisticsDetailsForposResponse.YunposLO;
import com.suning.rsf.consumer.ServiceLocator;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.dto.yxwt.BatchUpdateRevisitInfo;
import com.suning.sawp.dto.yxwt.CateInfo;
import com.suning.sawp.dto.yxwt.LogisticsStateConstant;
import com.suning.sawp.dto.yxwt.OrderStaffInfo;
import com.suning.sawp.dto.yxwt.RevisitInfo;
import com.suning.sawp.dto.yxwt.SaledNoPickDto;
import com.suning.sawp.dto.yxwt.SnpOrderInfo;
import com.suning.sawp.intf.model.ModelConstant;
import com.suning.sawp.intf.yxwt.SaledNoTakeService;
import com.suning.sawp.po.yxwt.SaledNoTake;
import com.suning.sawp.service.impl.dao.SaledNoTakeDaoService;
import com.suning.sawp.service.util.AESUtils;
import com.suning.sawp.service.util.BaseContants;
import com.suning.sawp.service.util.DJStringUtils;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.GsonUtils;

/**
 * 
 * 系统管理服务类<br>
 * 〈功能详细描述〉
 *
 * @author 14062606
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class SaledNoTakeServiceImpl implements SaledNoTakeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SaledNoTakeServiceImpl.class);

    private static final String OTHER_ORDER_FLAG = "other";

    private static final String YXWT_QUERY = "yxwt_query_";
    
    /**
     * 接口返回成功值
     */
    private static final String SUCCESS_CODE = "2";

    @Autowired
    SaledNoTakeDaoService saledNoTakeDaoService;

    @Resource
    JedisClient jedisClient;
    
    com.suning.lsq.rsf.query.StatusDetailsQueryService statusDetailsQueryService = ServiceLocator.getService(
            com.suning.lsq.rsf.query.StatusDetailsQueryService.class, "LSQ");

    @Override
    public ReturnMsg<List<SaledNoTake>> queryOrderList(int index, int size, String cateCode, String storeCode,
            String staffId, String accessStatus) {
        ReturnMsg<List<SaledNoTake>> returnMsg = new ReturnMsg<List<SaledNoTake>>();
        LOGGER.info(" SaledNoTakeServiceImpl queryOrderList index:" + index + ", size:" + size + ", cateCode:"
                + cateCode + ", storeCode:" + storeCode + ", staffId:" + staffId);
        List<SaledNoTake> resultList = saledNoTakeDaoService.queryOrderList(index, size, cateCode, storeCode, staffId,
                accessStatus);
        if (resultList != null) {
            for (SaledNoTake item : resultList) {
                item.setCustName(DJStringUtils.desensitiseName(item.getCustName()));
                String custMobile = item.getCustMobile();
                if (StringUtils.isBlank(custMobile)) {
                    item.setCustMobile(custMobile);
                } else {
                    item.setCustMobile(AESUtils.encrypt(item.getCustMobile(), ConfigConstants.AES_KEY));
                }
            }
            LOGGER.info(" SaledNoTakeServiceImpl queryOrderList resultList size:" + resultList.size());
            returnMsg.setData(resultList);
        } else {
            returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
            returnMsg.setRetFlag(ReturnMsg.FAIL);
            returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
        }
        return returnMsg;
    }

    @Override
    public ReturnMsg<List<CateInfo>> queryCateInfoByCateCodeList(StoreManDto storeMan, String cateCode) {
        ReturnMsg<List<CateInfo>> returnMsg = new ReturnMsg<List<CateInfo>>();
        String storeCode = storeMan.getStoreCode();
        LOGGER.info(" SaledNoTakeServiceImpl queryCateInfoByCateCodeList storeCode:" + storeCode);
        List<CateInfo> result = new ArrayList<CateInfo>();
        // 如果cateCode品类不为空，则通过品类查询本店的统计信息
        if (StringUtils.isNotBlank(cateCode)) {
            ReturnMsg<List<CateInfo>> storeCateResult = queryCateInfo(cateCode, storeCode);
            if (storeCateResult != null && ReturnMsg.SUCCESS.equals(storeCateResult.getRetFlag())) {
                result = storeCateResult.getData();
            } else {
                LOGGER.error("queryCateInfoByCateCodeList by cateCode error for cateCode:{},storeCode:{}", cateCode,
                        storeCode);
                returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
                returnMsg.setRetFlag(ReturnMsg.FAIL);
                returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
            }
        } else {
            // 默认情况，先查询本店所有的品类统计，然后将对应的角色品类筛选出来
            ReturnMsg<List<CateInfo>> storeCateResult = queryCateInfoByStore(storeCode);
            if (storeCateResult != null && ReturnMsg.SUCCESS.equals(storeCateResult.getRetFlag())) {
                List<CateInfo> storeCateList = storeCateResult.getData();

                if (!CollectionUtils.isEmpty(storeCateList)) {
                    // 将门店所有品类统计转化成MAP
                    Map<String, CateInfo> cateInfoMap = new HashMap<String, CateInfo>();
                    for (CateInfo item : storeCateList) {
                        if (item != null && StringUtils.isNotBlank(item.getCategoryCode())
                                && !cateInfoMap.containsKey(item.getCategoryCode())) {
                            cateInfoMap.put(item.getCategoryCode(), item);
                        }
                    }

                    // 过滤出该店员角色对应的品类统计
                    List<Category> cateCodeList = storeMan.getCategories();
                    if (CollectionUtils.isNotEmpty(cateCodeList)) {
                        for (Category item : cateCodeList) {
                            // 如果本店的品类结果中包含
                            if (item != null && StringUtils.isNotBlank(item.getCategoryCode())) {
                                if (cateInfoMap.containsKey(item.getCategoryCode())) {
                                    CateInfo detail = cateInfoMap.get(item.getCategoryCode());
                                    // 设置品类名称
                                    detail.setCategoryName(ModelConstant.getCommCateValue(item.getCategoryCode()));
                                    result.add(detail);
                                } else {
                                    // 如果该品类没有订单则返回空信息
                                    CateInfo newCateInfo = new CateInfo();
                                    newCateInfo.setCategoryCode(item.getCategoryCode());
                                    // 设置品类名称
                                    newCateInfo.setCategoryName(ModelConstant.getCommCateValue(item.getCategoryCode()));
                                    newCateInfo.setReVisitNum(0);
                                    newCateInfo.setTotalNum(0);
                                    newCateInfo.setWaitForSendNum(0);
                                    result.add(newCateInfo);
                                }
                            }
                        }
                    }
                }
            } else {
                LOGGER.error("queryCateInfoByCateCodeList by all_catecode  error for cateCode:{},storeCode:{}",
                        cateCode, storeCode);
                returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
                returnMsg.setRetFlag(ReturnMsg.FAIL);
                returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
            }
        }
        returnMsg.setData(result);
        return returnMsg;
    }

    @Override
    public ReturnMsg<List<CateInfo>> queryCateInfo(String cateCode, String storeCode) {
        ReturnMsg<List<CateInfo>> returnMsg = new ReturnMsg<List<CateInfo>>();
        LOGGER.info(" SaledNoTakeServiceImpl queryCateInfo storeCode：{},cateCode :{}", storeCode, cateCode);
        List<CateInfo> cateInfoList = saledNoTakeDaoService.queryCateInfoByCateCode(cateCode, storeCode);
        for (CateInfo item : cateInfoList) {
            if (item != null) {
                item.setCategoryName(ModelConstant.getCommCateValue(item.getCategoryCode()));
            }
        }
        returnMsg.setData(cateInfoList);
        return returnMsg;
    }

    @Override
    public ReturnMsg<List<CateInfo>> queryCateInfoByStore(String storeCode) {
        ReturnMsg<List<CateInfo>> returnMsg = new ReturnMsg<List<CateInfo>>();
        LOGGER.info(" SaledNoTakeServiceImpl queryCateInfoByStore storeCode:" + storeCode);
        List<CateInfo> cateInfoList = saledNoTakeDaoService.queryCateInfoByStore(storeCode);
        returnMsg.setData(cateInfoList);
        return returnMsg;
    }

    @Override
    public ReturnMsg<String> updateRevisit(String orderItemId, String content, String reVisitType) {
        ReturnMsg<String> returnMsg = new ReturnMsg<String>();
        LOGGER.info(" SaledNoTakeServiceImpl updateRevisit orderItemId:{},content:{},reVisitType:}" + orderItemId);
        boolean result = saledNoTakeDaoService.updateRevisit(orderItemId, content, reVisitType);
        if (!result) {
            LOGGER.error("updateRevisit   error for orderItemId:{},content:{}", orderItemId, content);
            returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
            returnMsg.setRetFlag(ReturnMsg.FAIL);
            returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
        }
        return returnMsg;
    }

    @Override
    public ReturnMsg<List<CateInfo>> queryCateInfoByCateCodeList(StoreManDto storeMan) {

        ReturnMsg<List<CateInfo>> returnMsg = new ReturnMsg<List<CateInfo>>();
        String storeCode = storeMan.getStoreCode();
        LOGGER.info(" SaledNoTakeServiceImpl queryCateInfoByCateCodeList storeCode:" + storeCode);
        List<CateInfo> result = new ArrayList<CateInfo>();
        if (ClerkConstants.STORE_KEEPER.equals(storeMan.getPositionId())) {
            // 如果是店长的话
            // 查询本店所有的品类统计
            result = saledNoTakeDaoService.queryCateInfoByStoreAll(storeCode);
            if (result == null) {
                LOGGER.error("queryCateInfoByCateCodeList by store_keeper error for cateCode:{},storeCode:{}",
                        storeCode);
                returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
                returnMsg.setRetFlag(ReturnMsg.FAIL);
                returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
            }
        } else {
            // 默认情况，先查询本店所有的品类统计，然后将对应的角色品类筛选出来
            ReturnMsg<List<CateInfo>> storeCateResult = queryCateInfoByStore(storeCode);
            if (storeCateResult != null && ReturnMsg.SUCCESS.equals(storeCateResult.getRetFlag())) {
                List<CateInfo> storeCateList = storeCateResult.getData();

                if (!CollectionUtils.isEmpty(storeCateList)) {
                    // 将门店所有品类统计转化成MAP
                    Map<String, CateInfo> cateInfoMap = new HashMap<String, CateInfo>();
                    for (CateInfo item : storeCateList) {
                        if (item != null && StringUtils.isNotBlank(item.getCategoryCode())
                                && !cateInfoMap.containsKey(item.getCategoryCode())) {
                            cateInfoMap.put(item.getCategoryCode(), item);
                        }
                    }

                    // 过滤出该店员角色对应的品类统计
                    List<Category> cateCodeList = storeMan.getCategories();
                    if (CollectionUtils.isNotEmpty(cateCodeList)) {
                        for (Category item : cateCodeList) {
                            // 如果本店的品类结果中包含
                            if (item != null && StringUtils.isNotBlank(item.getCategoryCode())) {
                                if (cateInfoMap.containsKey(item.getCategoryCode())) {
                                    CateInfo detail = cateInfoMap.get(item.getCategoryCode());
                                    // 设置品类名称
                                    detail.setCategoryName(ModelConstant.getCommCateValue(item.getCategoryCode()));
                                    result.add(detail);
                                } else {
                                    // 如果该品类没有订单则返回空信息
                                    CateInfo newCateInfo = new CateInfo();
                                    newCateInfo.setCategoryCode(item.getCategoryCode());
                                    // 设置品类名称
                                    newCateInfo.setCategoryName(ModelConstant.getCommCateValue(item.getCategoryCode()));
                                    newCateInfo.setReVisitNum(0);
                                    newCateInfo.setTotalNum(0);
                                    newCateInfo.setWaitForSendNum(0);
                                    result.add(newCateInfo);
                                }
                            }
                        }
                    }
                }
            } else {
                LOGGER.error("queryCateInfoByCateCodeList by all_catecode  error for cateCode:{},storeCode:{}",
                        storeCode);
                returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
                returnMsg.setRetFlag(ReturnMsg.FAIL);
                returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
            }
        }
        returnMsg.setData(result);
        return returnMsg;

    }

    @Override
    public ReturnMsg<SaledNoPickDto> queryOrderListByStatus(int index, int size, String cateCode, String storeCode,
            String staffId, String accessStatus) {
        ReturnMsg<SaledNoPickDto> returnMsg = new ReturnMsg<SaledNoPickDto>();
        StringBuilder sb = new StringBuilder(YXWT_QUERY).append(staffId).append(BaseContants._SPLIT).append(storeCode)
                .append(BaseContants._SPLIT).append(cateCode).append(BaseContants._SPLIT).append(accessStatus)
                .append(BaseContants._SPLIT).append(size).append(BaseContants._SPLIT).append(index);

        final String field = sb.toString();
        final String hKey = YXWT_QUERY+staffId;
        String json = jedisClient.execute(new JedisAction<String>() {
            @Override
            public String doAction(Jedis jedis) {
                return jedis.hget(hKey, field);
            }
        });

        if (StringUtils.isNotBlank(json)) {
            SaledNoPickDto saledNoPickDto = GsonUtils.fromJson(json, SaledNoPickDto.class);
            List<SnpOrderInfo> dtoList    = saledNoPickDto.getCustList();
            // 获取物流信息
            dtoList = fillLogistics(dtoList);
            saledNoPickDto.setCustList(dtoList);
            LOGGER.info(" SaledNoTakeServiceImpl queryOrderListByStatus  from jedis , saledNoPickDto :"
                    + saledNoPickDto);
            returnMsg.setData(saledNoPickDto);
            return returnMsg;
        }

        int waitConfirmNum = 0;
        int partConfirmNum = 0;
        int totalConfirmNum = 0;

        if (!SaledNoTake.AccConstants.TOTAL.equals(accessStatus)) {
            waitConfirmNum = saledNoTakeDaoService.queryOrderCountByStatus(cateCode, storeCode, staffId,
                    SaledNoTake.AccConstants.TOTAL_BACK_CALLED);
            partConfirmNum = saledNoTakeDaoService.queryOrderCountByStatus(cateCode, storeCode, staffId,
                    SaledNoTake.AccConstants.PART_BACK_CALLED);
            totalConfirmNum = saledNoTakeDaoService.queryOrderCountByStatus(cateCode, storeCode, staffId,
                    SaledNoTake.AccConstants.TOTAL_NO_BACK_CALLED);
        }

        LOGGER.info(" SaledNoTakeServiceImpl queryOrderListByStatus index:" + index + ", size:" + size + ", cateCode:"
                + cateCode + ", storeCode:" + storeCode + ", staffId:" + staffId);
        List<SaledNoTake> resultList = saledNoTakeDaoService.queryOrderListByStatus(index, size, cateCode, storeCode,
                staffId, accessStatus);

        // 将查询结果根据客户手机号码进行分组
        ImmutableCollection<Collection<SaledNoTake>> tmpMap = Multimaps
                .index(resultList, new Function<SaledNoTake, String>() {
                    @Override
                    public String apply(SaledNoTake input) {
                        return input.getCustMobile();
                    }
                }).asMap().values();
        // 对每个客户的订单信息进行区分开单人
        final String staffIdTem = staffId;
        LOGGER.info(" SaledNoTakeServiceImpl queryOrderListByStatus   , tmpMap :" + tmpMap);
        List<SnpOrderInfo> dtoList = Lists.newArrayList(Iterables.transform(tmpMap,
                new Function<Collection<SaledNoTake>, SnpOrderInfo>() {
                    @Override
                    public SnpOrderInfo apply(Collection<SaledNoTake> input) {
                        SnpOrderInfo snpOrderInfo = getSnpOrderInfo(input, staffIdTem);
                        return snpOrderInfo;
                    }
                }));

        if (dtoList != null) {
            SaledNoPickDto saledNoPickDto = new SaledNoPickDto();
            
            // 获取物流信息
            dtoList = fillLogistics(dtoList);
            
            saledNoPickDto.setCustList(dtoList);
            saledNoPickDto.setLimitTime(DateUtils.getDateStrByFormat(DateUtils.getNextDay(new Date(), -1),
                    DateUtils.DEFAULT_DATE_PATTERN));
            saledNoPickDto.setPartConfirmNum(String.valueOf(partConfirmNum));
            saledNoPickDto.setTotalConfirmNum(String.valueOf(totalConfirmNum));
            saledNoPickDto.setWaitConfirmNum(String.valueOf(waitConfirmNum));
            LOGGER.info(" SaledNoTakeServiceImpl queryOrderListByStatus  end , saledNoPickDto :" + saledNoPickDto);
            addSaledNoPickDto2Cache(saledNoPickDto, sb.toString(),staffId);
            returnMsg.setData(saledNoPickDto);
        } else {
            LOGGER.info(" SaledNoTakeServiceImpl queryOrderListByStatus  error end ");
            returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
            returnMsg.setRetFlag(ReturnMsg.FAIL);
            returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
        }
        return returnMsg;

    }

	/**
	 * 
	 * 功能描述: 根据订单信息来获取物流信息<br>
	 * 〈功能详细描述〉
	 *
	 * @param dtoList
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private List<SnpOrderInfo> fillLogistics(List<SnpOrderInfo> dtoList) {
	    // 所有的客户订单
	    List<String> orderItemIdList = new ArrayList<String>();
		for (SnpOrderInfo info : dtoList) {
		    if (null != info.getMyOrderList()) {
		        for (SaledNoTake take : info.getMyOrderList()) {
		            orderItemIdList.add(take.getOrderItemId());
		        }
		    }
		    if (null != info.getOtherOrderList()) {
		        for (SaledNoTake take : info.getOtherOrderList()) {
		            orderItemIdList.add(take.getOrderItemId());
		        }
		    }
		}
		
		// 调用接口获取状态编码和名称，并对返回码进行转译
		Map<String, String> stateCodeMap = queryLogisticsState(orderItemIdList);
		
        for (SnpOrderInfo info : dtoList) {
            if (null != info.getMyOrderList()) {
                for (SaledNoTake take : info.getMyOrderList()) {
                    String stateCode = StringUtils.isBlank(stateCodeMap.get(take.getOrderItemId())) ? LogisticsStateConstant.LOGI_STATE_E001
                            : stateCodeMap.get(take.getOrderItemId());
                    String stateName = LogisticsStateConstant.LOGISTICS_STATE_MAP.get(stateCode);
                    take.setLogisticsStateCode(stateCode);
                    take.setLogisticsStateName(stateName);
                }
            }
            if (null != info.getOtherOrderList()) {
                for (SaledNoTake take : info.getOtherOrderList()) {
                    String stateCode = StringUtils.isBlank(stateCodeMap.get(take.getOrderItemId())) ? LogisticsStateConstant.LOGI_STATE_E001
                            : stateCodeMap.get(take.getOrderItemId());
                    String stateName = LogisticsStateConstant.LOGISTICS_STATE_MAP.get(stateCode);
                    take.setLogisticsStateCode(stateCode);
                    take.setLogisticsStateName(stateName);
                }
            }
        }
		return dtoList;
	}

	/**
	 * 
	 * 功能描述: 调用接口获取状态编码和名称，并对返回码进行转译<br>
	 * 〈功能详细描述〉
	 *
	 * @param orderItemIdList
	 * @return map<orderItemId, logiState>
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
    private Map<String, String> queryLogisticsState(List<String> orderItemIdList) {
        Map<String, String> rspMap = new HashMap<String, String>();
        QueryLogisticsDetailsForposRequest req = new QueryLogisticsDetailsForposRequest();
        
        // 循环调用接口
        int batchSearchNum = 20;
        int flagNum = 0;
        List<String> searchOrderItemIdList = new ArrayList<String>();
        for (int i = 0; i < orderItemIdList.size(); i++) {
            if (flagNum < batchSearchNum) {
                if (null != orderItemIdList.get(i)) {
                    searchOrderItemIdList.add(orderItemIdList.get(i));
                    flagNum++;
                }
            }
            if (flagNum >= batchSearchNum || i == (orderItemIdList.size() - 1)) {
                req.setOrderItemIdList(searchOrderItemIdList);
                QueryLogisticsDetailsForposResponse rsp = statusDetailsQueryService.queryLgsStatusDetailsForPOS(req);
                LOGGER.info("queryLogisticsState.rsp:" + rsp);
                if (null != rsp && CollectionUtils.isNotEmpty(rsp.getYloList())) {
                    for (YunposLO lo : rsp.getYloList()) {
                        if (SUCCESS_CODE.equals(lo.getReturnCode()) && CollectionUtils.isNotEmpty(lo.getPosList())) {
                            for (QueryLogisticsDetailsForpos pos : lo.getPosList()) {
                                String orderItemId = pos.getOrderItemId();
                                String operateTypeCode = pos.getOperateTypeCode();
                                String logisticsState;
                                if (StringUtils.isBlank(operateTypeCode)) {
                                    // 无返回码，显示"待发货"
                                    logisticsState = LogisticsStateConstant.LOGI_STATE_E001;
                                } else if (!LogisticsStateConstant.INTERFACE_CODE_MAP.containsKey(operateTypeCode)) {
                                    // 返回码，不是范围内，显示"查看物流"
                                    logisticsState = LogisticsStateConstant.LOGI_STATE_DJWL;
                                    LOGGER.info(String
                                            .format("queryLogisticsState.No valid parameters are obtained.OrderItemId: %s, operateTypeCode: %s",
                                                    operateTypeCode, orderItemId));
                                } else {
                                    logisticsState = LogisticsStateConstant.INTERFACE_CODE_MAP.get(operateTypeCode);
                                }
                                rspMap.put(orderItemId, logisticsState);
                            }
                        }
                    }
                }
                // 重置调用条件
                flagNum = 0;
                searchOrderItemIdList.clear();
            }
        }
        return rspMap;
    }

    private void addSaledNoPickDto2Cache(SaledNoPickDto saledNoPickDto, String keyInfo,String staffId) {
        final String json = GsonUtils.toJson(saledNoPickDto, false);
        final String field = keyInfo;
        final String key = YXWT_QUERY+staffId;
        
        final long  redisExpireTime =redisExpireTime();
        jedisClient.execute(new JedisAction<String>() {
            @Override
            public String doAction(Jedis jedis) {
                jedis.hset(key, field, json);
                jedis.expireAt(key, redisExpireTime);
                return null;
            }
        });

    }

    /**
     * 
     * 功能描述: redis失效时间<br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private long redisExpireTime() {
        // 取当前时间的小时数和分钟数
        Date tomorrowZeroPoint = DateUtils.getNextDay(DateUtils.getNowZeroPoint(), 1);
        return tomorrowZeroPoint.getTime() / 1000;
    }
    /**
     * 对客户的订单信息进行分组，区分出当前店员开单还是其他店员开单 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param saledNoTakeList
     * @param staffId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private SnpOrderInfo getSnpOrderInfo(Collection<SaledNoTake> saledNoTakeList, String staffId) {
        SnpOrderInfo snpOrderInfo = new SnpOrderInfo();
        final String staffIdTem = staffId;
        ImmutableMap<String, Collection<SaledNoTake>> orderMap = Multimaps.index(saledNoTakeList,
                new Function<SaledNoTake, String>() {
                    @Override
                    public String apply(SaledNoTake input) {
                        if (StringUtils.isNotBlank(staffIdTem) && staffIdTem.equals(input.getStaffId())) {
                            // 对客户名称进行脱敏，对客户手机号码进行加密
                            input.setCustName(DJStringUtils.desensitiseName(input.getCustName()));
                            String custMobile = input.getCustMobile();
                            if (StringUtils.isBlank(custMobile)) {
                                input.setCustMobile(custMobile);
                            } else {
                                input.setCustMobile(AESUtils.encrypt(input.getCustMobile(), ConfigConstants.AES_KEY));
                            }
                            return input.getStaffId();
                        } else {
                            return OTHER_ORDER_FLAG;
                        }
                    }
                }).asMap();

        if (orderMap == null) {
            LOGGER.error("getSnpOrderInfo error orderMap is null for staff " + staffId);
            return snpOrderInfo;
        }

        // 设置客户订单中不属于当前操作工号的订单
        if (CollectionUtils.isNotEmpty(orderMap.get(OTHER_ORDER_FLAG))) {
            List<SaledNoTake> otherOrderList = Lists.newArrayList(orderMap.get(OTHER_ORDER_FLAG));
            try {
                Collections.sort(otherOrderList, new Comparator<SaledNoTake>() {
                    @Override
                    public int compare(SaledNoTake o1, SaledNoTake o2) {
                        if (StringUtils.isBlank(o2.getOrderTime()) && StringUtils.isBlank(o1.getOrderTime())) {
                            return 0;
                        }
                        if (StringUtils.isBlank(o1.getOrderTime())) {
                            return -1;
                        }
                        if (StringUtils.isBlank(o2.getOrderTime())) {
                            return 1;
                        }
                        return o1.getOrderTime().compareTo(o2.getOrderTime());
                    }
                });
            } catch (Exception e) {
                LOGGER.error("Collections error ", e);
            }

            snpOrderInfo.setOtherOrderList(otherOrderList);
        }

        // 设置客户订单中属于当前操作工号的订单
        // 订单时间顺序排序
        if (CollectionUtils.isNotEmpty(orderMap.get(staffId))) {
            List<SaledNoTake> myOrderList = Lists.newArrayList(orderMap.get(staffId));
            try {
                Collections.sort(myOrderList, new Comparator<SaledNoTake>() {
                    @Override
                    public int compare(SaledNoTake o1, SaledNoTake o2) {
                        if (StringUtils.isBlank(o2.getOrderTime()) && StringUtils.isBlank(o1.getOrderTime())) {
                            return 0;
                        }
                        if (StringUtils.isBlank(o1.getOrderTime())) {
                            return -1;
                        }
                        if (StringUtils.isBlank(o2.getOrderTime())) {
                            return 1;
                        }
                        return o1.getOrderTime().compareTo(o2.getOrderTime());
                    }
                });
            } catch (Exception e) {
                LOGGER.error("Collections error ", e);
            }
            SaledNoTake saledNoTake = myOrderList.get(0);
            snpOrderInfo.setCustMobile(myOrderList.get(0).getCustMobile());
            snpOrderInfo.setCustName(myOrderList.get(0).getCustName());
            snpOrderInfo.setRevisitTime(saledNoTake.getRevisitTime());
            snpOrderInfo.setMyOrderList(myOrderList);
        }

        return snpOrderInfo;
    }

    public static void main(String[] args) {
        SaledNoTake test1 = new SaledNoTake();
        test1.setRevisitTime("2016-11-11");
        SaledNoTake test2 = new SaledNoTake();
        test2.setRevisitTime("2016-11-01");
        SaledNoTake test3 = new SaledNoTake();
        SaledNoTake test4 = new SaledNoTake();
        List<SaledNoTake> myOrderList = Lists.newArrayList(test3, test4, test1, test2);
        Collections.sort(myOrderList, new Comparator<SaledNoTake>() {
            @Override
            public int compare(SaledNoTake o1, SaledNoTake o2) {
                if (StringUtils.isBlank(o2.getRevisitTime()) && StringUtils.isBlank(o1.getRevisitTime())) {
                    return 0;
                }
                if (StringUtils.isBlank(o2.getRevisitTime())) {
                    return -1;
                }
                if (StringUtils.isBlank(o1.getRevisitTime())) {
                    return 1;
                }
                return o2.getRevisitTime().compareTo(o1.getRevisitTime());
            }
        });

        System.out.println(myOrderList);
    }

    @Override
    public ReturnMsg<String> batchUpdateRevisit(BatchUpdateRevisitInfo batchUpdateRevisitInfo, StoreManDto storeManDto) {
        ReturnMsg<String> returnMsg = new ReturnMsg<String>();
        LOGGER.info(" SaledNoTakeServiceImpl batchUpdateRevisit batchUpdateRevisitInfo:{}", batchUpdateRevisitInfo);
        boolean result = saledNoTakeDaoService.batchUpdateRevisit(batchUpdateRevisitInfo);
        if (!result) {
            LOGGER.error(" SaledNoTakeServiceImp errorl batchUpdateRevisit batchUpdateRevisitInfo:{}",
                    batchUpdateRevisitInfo);
            returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
            returnMsg.setRetFlag(ReturnMsg.FAIL);
            returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
        } else {
            // 删除登录人的已销未提缓存
            clearYxwtCache(storeManDto.getStaffId());
            if (CollectionUtils.isNotEmpty(batchUpdateRevisitInfo.getMyOrderList())) {
                RevisitInfo revisitInfo = batchUpdateRevisitInfo.getMyOrderList().get(0);
                if (null != revisitInfo && StringUtils.isNotBlank(revisitInfo.getOrderStaffId()) 
                        && !storeManDto.getStaffId().equals(revisitInfo.getOrderStaffId())) {
                    // 删除开单人工号对应的已销未提缓存
                    clearYxwtCache(revisitInfo.getOrderStaffId());
                }
            }
        }
        return returnMsg;

    }

    /**
     * 
     * 功能描述: 清除工号对应的已销未提缓存<br>
     * 〈功能详细描述〉
     *
     * @param staffId
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private void clearYxwtCache(String staffId) {
        List<String> indexList = saledNoTakeDaoService.queryCacheIndex(staffId);
        for (String index : indexList) {
            if(StringUtils.isNotBlank(index)){
                StringBuilder sb = new StringBuilder(YXWT_QUERY).append(index);
                final String key = sb.toString();
                try {
                    jedisClient.execute(new JedisAction<Long>() {
                        @Override
                        public Long doAction(Jedis jedis) {
                            return jedis.del(key);
                        }
                    });
                } catch (Exception e) {
                    LOGGER.error(" SaledNoTakeServiceImp jedisClient error batchUpdateRevisit",e);
                }
            }
        }
    }
    
    @Override
    public ReturnMsg<List<OrderStaffInfo>> queryOrderCountByCata(String cateCode, StoreManDto storeManDto) {
        ReturnMsg<List<OrderStaffInfo>> returnMsg = new ReturnMsg<List<OrderStaffInfo>>();
        LOGGER.info(" SaledNoTakeServiceImpl queryOrderCountByCata catacode:{}", cateCode);
        List<OrderStaffInfo> result = saledNoTakeDaoService.queryOrderCountByCata(cateCode, storeManDto.getStoreCode());
        if (result == null) {
            LOGGER.error(" SaledNoTakeServiceImp errorl queryOrderCountByCata catacode:{}", cateCode);
            returnMsg.setErrorCode(ErrorCodeConstants.ERR_0028);
            returnMsg.setRetFlag(ReturnMsg.FAIL);
            returnMsg.setErrorMessage(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0028));
        } else {
            returnMsg.setData(result);
        }
        return returnMsg;
    }
}
